package com.huixh.train.business.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.huixh.train.business.domain.DailyTrainStation;
import com.huixh.train.business.domain.DailyTrainStationExample;
import com.huixh.train.business.domain.TrainStation;
import com.huixh.train.business.domain.TrainStationExample;
import com.huixh.train.business.mapper.DailyTrainStationMapper;
import com.huixh.train.business.mapper.TrainStationMapper;
import com.huixh.train.business.req.DailyTrainStationQueryReq;
import com.huixh.train.business.req.DailyTrainStationSaveReq;
import com.huixh.train.business.resp.DailyTrainStationQueryResp;
import com.huixh.train.business.service.DailyTrainStationService;
import com.huixh.train.common.resp.PageResult;
import com.huixh.train.common.resp.Result;
import com.huixh.train.utils.random.SnowUtil;
import jakarta.annotation.Nullable;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
* @author huixh
*/
@Service
public class DailyTrainStationServiceImpl implements DailyTrainStationService {

    private final Logger logger = LoggerFactory.getLogger(DailyTrainStationServiceImpl.class);
    @Resource
    private DailyTrainStationMapper dailyTrainStationMapper;
    @Resource
    private TrainStationMapper trainStationMapper;


    @Resource
    private SnowUtil snowUtil;

    @Override
    public void save(DailyTrainStationSaveReq dailyTrainStationSaveReq) {
        DateTime now = DateTime.now();
        DailyTrainStation dailyTrainStation = BeanUtil.copyProperties(dailyTrainStationSaveReq, DailyTrainStation.class);


        if (ObjectUtil.isNull(dailyTrainStation.getId())) {
            dailyTrainStation.setId(snowUtil.getSnowflakeToLong());
            dailyTrainStation.setCreateTime(now);
            dailyTrainStation.setUpdateTime(now);
            dailyTrainStationMapper.insert(dailyTrainStation);
        } else {
            dailyTrainStation.setUpdateTime(now);
            dailyTrainStationMapper.updateByPrimaryKey(dailyTrainStation);
        }
    }

    @Override
    public PageResult <List<DailyTrainStationQueryResp>> queryList(DailyTrainStationQueryReq dailyTrainStationQueryReq) {
        DailyTrainStationExample dailyTrainStationExample = new DailyTrainStationExample();
        dailyTrainStationExample.setOrderByClause("`date` desc, train_code asc, `index` asc");
        DailyTrainStationExample.Criteria criteria = dailyTrainStationExample.createCriteria();
        if (ObjectUtil.isNotNull(dailyTrainStationQueryReq.getDate())) {
            criteria.andDateEqualTo(dailyTrainStationQueryReq.getDate());
        }

        if (StrUtil.isNotBlank(dailyTrainStationQueryReq.getTrainCode())) {
            criteria.andTrainCodeEqualTo(dailyTrainStationQueryReq.getTrainCode());
        }

        logger.info("查询页码：{}", dailyTrainStationQueryReq.getPageNum());
        logger.info("每页条数：{}", dailyTrainStationQueryReq.getPageSize());
        PageHelper.startPage(dailyTrainStationQueryReq.getPageNum(), dailyTrainStationQueryReq.getPageSize());
        List<DailyTrainStation> dailyTrainStationList = dailyTrainStationMapper.selectByExample(dailyTrainStationExample);

        PageInfo<DailyTrainStation> pageInfo = new PageInfo<>(dailyTrainStationList);
        logger.info("总行数：{}", pageInfo.getTotal());
        logger.info("总页数：{}", pageInfo.getPages());

        List<DailyTrainStationQueryResp> list = BeanUtil.copyToList(dailyTrainStationList, DailyTrainStationQueryResp.class);
        return PageResult.success(pageInfo.getTotal(), list);
    }

    @Override
    public void delete(Long id) {
        dailyTrainStationMapper.deleteByPrimaryKey(id);
    }
    public @Nullable DailyTrainStation selectDateTrainCodeIndexUnique(String trainCode, Integer index){
        DailyTrainStationExample dailyTrainStationExample = new DailyTrainStationExample();
        DailyTrainStationExample.Criteria criteria = dailyTrainStationExample.createCriteria();
        criteria.andTrainCodeEqualTo(trainCode);
        criteria.andIndexEqualTo(index);
        List<DailyTrainStation> stations = dailyTrainStationMapper.selectByExample(dailyTrainStationExample);
        if(CollUtil.isEmpty(stations)){
            return null;
        } else {
            return stations.get(0);
        }
    }

    public @Nullable DailyTrainStation selectDateTrainCodeNameUnique(Date date, String trainCode, String name) {
        DailyTrainStationExample dailyTrainStationExample = new DailyTrainStationExample();
        DailyTrainStationExample.Criteria criteria = dailyTrainStationExample.createCriteria();
        criteria.andDateEqualTo(date);
        criteria.andTrainCodeEqualTo(trainCode);
        criteria.andNameEqualTo(name);
        List<DailyTrainStation> dailyTrainStations = dailyTrainStationMapper.selectByExample(dailyTrainStationExample);
        if (CollUtil.isEmpty(dailyTrainStations)){
            return null;
        } else {
            return dailyTrainStations.get(0);
        }
    }

    /**
     * 生成每次车次车站信息数据
     *
     * @param trainCode 列车号
     * @param date      生成时间
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<String> genDailyTrainStation(String trainCode, Date date) {

        logger.info("开始生成日期:【{}】车次【{}】的车站信息",DateUtil.formatDate(date),trainCode);
        DailyTrainStationExample removeExample = new DailyTrainStationExample();
        removeExample.createCriteria()
                .andTrainCodeEqualTo(trainCode)
                .andDateEqualTo(date);
        dailyTrainStationMapper.deleteByExample(removeExample);

        List<TrainStation> trainStations = selectByTrainCode(trainCode);
        if (CollUtil.isEmpty(trainStations)){
            return Result.fail("该车次没有车站信息，任务结束");
        }
        List<DailyTrainStation> batchTrainStationList = new ArrayList<>(trainStations.size());
        trainStations.forEach(trainStation -> {
            DateTime now = DateTime.now();
            DailyTrainStation dailyTrainStation = BeanUtil.copyProperties(trainStation, DailyTrainStation.class);
            dailyTrainStation.setId(snowUtil.getSnowflakeToLong());
            dailyTrainStation.setCreateTime(now);
            dailyTrainStation.setUpdateTime(now);
            dailyTrainStation.setDate(date);
            //dailyTrainStationMapper.insert(dailyTrainStation);
            batchTrainStationList.add(dailyTrainStation);
        });

        dailyTrainStationMapper.batchInsert(batchTrainStationList);

        logger.info("日期:【{}】车次:【{}】的车站信息,生成成功。", DateUtil.formatDate(date),trainCode);
        return Result.success("生成成功");
    }

    public List<TrainStation> selectByTrainCode(String trainCode){
        TrainStationExample trainStationExample = new TrainStationExample();
        trainStationExample.setOrderByClause("`index` asc");
        trainStationExample.createCriteria().andTrainCodeEqualTo(trainCode);
        return trainStationMapper.selectByExample(trainStationExample);
    }

    /**
     * 获取车次
     *
     * @param date 日期
     * @param trainCode 车次号
     * @return 当前车次有多少车站
     */
    @Override
    public Long countByTrainCodeAndDate(Date date, String trainCode) {
        DailyTrainStationExample trainStationExample = new DailyTrainStationExample();
        trainStationExample.createCriteria()
                .andDateEqualTo(date)
                .andTrainCodeEqualTo(trainCode);
        return dailyTrainStationMapper.countByExample(trainStationExample);
    }
}